package com.ww.java.generic;

import java.util.ArrayList;
import java.util.List;

/**
 * 原生类型List和参数化类型List<Object>之间到底有什么区别？
 * 不严格的说，前者逃避了泛型检查，后者则明确告知编译器，它能够持有任意类型的对象。
 * 虽然你可以将List<String>传递给类型List的参数，但是不能将它传给类型为List<Object>的参数。
 * 泛型有子类型化(subtyping)的规则，List<String>是原生态类型List的一个子类型，而不是参数化类型List<Object>的子类型。
 * 
 * 因此，如果使用像List这样的原生态类型，就会失掉类型安全性，但是如果使用像List<Object>这样的参数化类型，则不会。
 */
public class GenericDemo2 {

	public static void main(String[] args) {
		test01();
	}
	
	@SuppressWarnings({ "removal", "unused" })
	private static void test02() {
		/**
		 * 编译期间就会报错
		 * Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
	at com.ww.java.generic.GenericDemo2.test02(GenericDemo2.java:25)
	at com.ww.java.generic.GenericDemo2.main(GenericDemo2.java:18)
		 */
		List<String> strings = new ArrayList<>();
		unsafeAdd(strings, new Integer(4));
		String s = strings.get(0);
	}
	
	@SuppressWarnings({ "removal" })
	private static void test01() {
		List<String> strings = new ArrayList<>();
		unsafeAdd(strings, new Integer(4));
		/**
		 * 只有到转换才会报错
		 * Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
	at com.ww.java.generic.GenericDemo2.main(GenericDemo2.java:20)
		 */
//		String s = strings.get(0);
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static void unsafeAdd(List list, Object o) {
		list.add(o);
	}
	
	@SuppressWarnings("unused")
	private static void unsafeAdd2(List<Object> list, Object o) {
		list.add(o);
	}
}
